import hashlib
import uuid

from app.config.webapp import WxappConfig
from app.schema.ai import AiUpdateSchema
from app.service.base import BaseService
from app.service.chat import ChatService
from app.utils.obj2dict import obj2dict
from app.utils.oss2_upload import Oss2UploadUtil
from app.utils.redis import RedisUtils
from app.utils.wxapp import WxappUtils
from app.utils.auth import  create_access_token, create_refresh_token
from app.dao.ai import AiDao
from app.dao.file import FileDao
from ..dao.user import UserDao
from ..dao.chat import ChatDao
from ..model.user import User
from ..schema.auth import AuthDataSchema,Token,UserInfoSchema
from ..schema.base import ListArgsSchema, ListFilterSchema, RespBaseSchema
from ..utils.paste import paste_image

class UserService(BaseService):
    def __init__(self, auth_data: UserInfoSchema = None):
        auth_data = UserInfoSchema() if not auth_data else auth_data

        user_id = auth_data.id
        self.Model = User
        self.dao = UserDao(user_id)
        self.dao.Model = User
        self.redis = RedisUtils()
        self.wxapp = WxappUtils(WxappConfig())

        super().__init__(user_id, auth_data)

    async def login_by_code(self, code: str):
        """
        通过微信登录code进行登录
        :param code:
        :return:
        """
        print(code,'code--code')
        data =await self.wxapp.jscode2session(code)
        print(data,type(data))
        if 'openid' not in data:
            return {
                'code': 500,
                'message': '错误：jscode2session'
            }
        res=await self.login_by_openid(data['openid'])
        return res

    def login_by_token(self, token: str):
        """
        通过自产token进行登录
        :param token:
        :return:
        """

        data = self.redis.get('token:' + token)

        if not data:
            return {
                'code': 500,
                'message': '错误：token错误'
            }

        # 删除当前token，因为会重新创建
        self.redis.delete('token:' + token)

        return self._login_by_id(data['user']['id'])

    async def login_by_openid(self, openid: str):
        """
        通过openid进行登录
        :param openid:
        :return:
        """
        user = self.dao.read_by_openid(openid)
        if not user:
            user = User(openid=openid)
            user.openid = openid
            self.dao.create(user)
        return self._login_success(user)

    def _login_success(self, user,msg='登录成功'):
        data={
           "id":user.id,
           "name":user.name,
           "avatar":user.avatar,
       }
        print(data,'用户data数据')
        access_token=create_access_token(data)
        refresh_token=create_refresh_token(data)
        res=AuthDataSchema(code=200,message=msg,data=Token(access_token=access_token,refresh_token=refresh_token))
        print(res,'登录成功返回数据')
        return res

    def _login_by_id(self, id: int):
        """
        通过id进行登录
        :param openid:
        :return:
        """

        user = self.dao.read(id)

        if not user:
            return {
                'code': 2008061621,
                'message': '用户不存在'
            }

        return self._login_success(user)

    def login_by_password(self, username: str, password: str):
        """
        通过username、password进行登录
        :param username:
        :param password:
        :return:
        """

        user = self.dao.read_by_username(username)

        if not user:
            return {
                'code': 2008061621,
                'message': '用户不存在'
            }

        if user.password != hashlib.md5((user.name + password).encode(encoding='UTF-8')).hexdigest():
            return {
                'code': 2008061622,
                'message': '密码错误'
            }

        return self._login_success(user)

    def refresh_token(self,auth_data: dict):
        return self._login_success(auth_data,msg='刷新成功')
    
    def read_me(self, auth_data: dict):
        resp=self.read(id=auth_data.id)
        chatdao = ChatDao()
        ai_resp= AiDao().read_by_user_id(auth_data.id)
        file_resp= FileDao().read_by_user_id(auth_data.id)
        group_args = ListArgsSchema(filters=[ListFilterSchema(key='group_id',value=auth_data.id,condition='=')])
        group_chat_list = chatdao.read_list(group_args)
        uaer_args = ListArgsSchema(filters=[ListFilterSchema(key='user_id',value=auth_data.id,condition='=')])
        user_chat_list = chatdao.read_list(uaer_args)
        data={
            "id":resp.id,
            "name":resp.name,
            "avatar":resp.avatar,
            "ai_id":ai_resp.id if ai_resp else None,
            "file_num" : len(file_resp),
            "add_num": ai_resp.add_num if ai_resp else 0,
            "chat_num": group_chat_list.count,
            "ai_num": user_chat_list.count,
            "is_vip": True
        }

        return data
    
    async def get_group_info(self, ai_id:int):
        ai_info = AiDao().read(ai_id)
        if not ai_info:
          return 'Ai不存在'
        else:
            user_info = self.dao.read(ai_info.user_id)
            if not user_info:
                return '用户不存在'
            else:
                return {"name":user_info.name, "avatar":user_info.avatar, "url":ai_info.url}
            
    async def update_ai_page(self, user:UserInfoSchema):
        ai_dao = AiDao()
        ai_info = ai_dao.read_by_user_id(user.id)
        if ai_info:
            data = await paste_image(user.avatar,ai_info.page)
            page = await Oss2UploadUtil().upload('img',ai_info.vector_name + 'a',data)
            ai_info.page=page
            ai_dao.update(ai_info)